package player

import (
	"GameServer/Common/utils"
	"GameServer/conf"
	"fmt"
	"strconv"
	"strings"
	"time"

	"GameServer/Common/data"
	"GameServer/Game/activity"
	"GameServer/Game/activity_rank"
	"GameServer/Game/entrust_activ"
	"GameServer/Game/entrust_rank"
	"GameServer/Game/errors"
	"GameServer/Game/jackpot"
	"GameServer/Game/lib"
	"GameServer/Game/m"
	"GameServer/Game/mulcombat"
	"GameServer/Game/slot_steal"
	"GameServer/Game/sp"

	log "github.com/sirupsen/logrus"
)

func (p *Player) GmRequest(req *sp.GmRequest) (res *sp.GmResponse, err error) {
	// 不是超级管理员账号，直接无视。
	if p.User.SuperAccount != 1 {
		return
	}

	if !conf.Conf.Gm {
		return
	}

	if req.Cmd == "" {
		return
	}

	index := strings.Index(req.Cmd, ":")
	var (
		cmd  string
		args string
	)
	if index > 0 {
		cmd = req.Cmd[:index]
		args = req.Cmd[index+1:]
	} else {
		cmd = req.Cmd
	}

	fmt.Println("cmd:", cmd, "args:", args)

	switch cmd {
	case "res":
		lines := strings.Split(args, ":")
		if len(lines) != 2 {
			return
		}
		val, _ := strconv.ParseInt(lines[1], 10, 64)
		var uprop *m.UpdateProp
		if val < 0 {
			key, _ := strconv.ParseInt(lines[0], 10, 64)
			kv := m.BaseKV{Key: key, Val: -val}
			uprop, err = lib.Cost("GmRequest", p.User, []m.BaseKV{kv})
			if err != nil {
				res = &sp.GmResponse{
					Errcode: errors.ErrCode(err),
				}
				return res, err
			}
		} else {

			flag := strings.HasSuffix(lines[0], "X")

			// 支持前缀给物品
			keyStr := strings.Replace(lines[0], "X", "", -1)

			if keyStr == "" {
				return nil, nil
			}

			itemList := make([]m.BaseKV, 0)

			if flag {
				lists, ok := data.GetAllDatas("Goods")
				if !ok {
					return nil, nil
				}
				for _, item0 := range lists {
					item := item0.(data.Good)
					if strings.HasPrefix(strconv.Itoa(int(item.Id)), keyStr) || strconv.Itoa(int(item.Id)) == keyStr {
						itemList = append(itemList, m.BaseKV{Key: int64(item.Id), Val: val})
					}
				}
			} else {
				key, _ := strconv.ParseInt(lines[0], 10, 64)
				itemList = append(itemList, m.BaseKV{Key: key, Val: val})
			}

			uprop, _, _, err = lib.GiveGoodsByKvList("GmRequest", p.User, itemList, p.Send)
			if err != nil {
				res = &sp.GmResponse{
					Errcode: 1,
				}
				return res, err
			}
		}
		defer func() {
			if uprop != nil {
				// p.TimelyUpdateProp(req.GetType(), uProp)
				go p.UpdateProp(req.GetType(), uprop)
			}

		}()
		res = &sp.GmResponse{}
		return res, nil
	case "layer": // 开启该层
		p.gmOpenAllLayerGrids()
	case "lockBlock":
		p.gmOpenAllLockBlockGrids()
	case "lockBlockOpen":
		block, _ := strconv.ParseInt(args, 10, 64)
		p.gmLockBlockOpen(block)
	case "slotKey":
		key, _ := strconv.ParseInt(args, 10, 64)
		p.PutData("slotKeyGm", uint64(key))
	case "slotUser":
		p.gmSlotUser(args)
	case "fireUser":
		p.gmFireUser(args)
	case "fireUserOn":
		p.gmFireUserOn(args)
	case "setHideShopFireNum":
		readySetHideShipFireNum, err := strconv.ParseInt(args, 10, 64)
		if err == nil {
			lib.SetHideShopFireNum(p.User, readySetHideShipFireNum)
		}
	case "newHideShop":
		err = lib.GmNewHideShop(p.User)
		if err != nil {
			res = &sp.GmResponse{
				Errcode: errors.ErrCode(err),
			}
		}
		return res, err
	case "energyTime":
		timeNum, err := strconv.ParseInt(args, 10, 64)
		if err != nil {
			res = &sp.GmResponse{
				Errcode: errors.ErrCode(err),
			}
			return res, err
		}
		p.gmChangeErengyTime(req, timeNum)
	case "rank":
		// m.RankSort()
	case "addScryBuff":
		gmBuffId, err := strconv.ParseInt(args, 10, 64)
		if err == nil {
			fmt.Println("GM生成占卜buff:", gmBuffId)
			p.gmAddScryBuff(gmBuffId)
		}
	case "addAvatarFrame":
		avatarFrameId, err := strconv.ParseInt(args, 10, 64)
		if err == nil {
			needCallClient, curFrame, curFrameArr := p.User.AddAvatarFrame(avatarFrameId)
			if needCallClient {
				p.Send(&sp.AvatarFrameUpdateRequest{
					AvatarFrame:    curFrame,
					AvatarFrameArr: lib.FormatAvatarFramesArr(curFrameArr),
				})
			}
		}
	case "removeAvatarFrame":
		avatarFrameId, err := strconv.ParseInt(args, 10, 64)
		if err == nil {
			needCallClient, curFrame, curFrameArr := p.User.RemoveAvatarFrame(avatarFrameId)
			if needCallClient {
				p.Send(&sp.AvatarFrameUpdateRequest{
					AvatarFrame:    curFrame,
					AvatarFrameArr: lib.FormatAvatarFramesArr(curFrameArr),
				})
			}
		}
	case "getSpBoxByMail":
		var mailTitle string = "测试5选1宝箱"
		var mailContent string = "玄不改命，氪不救非"
		resGoods := make([]*m.Goods, 0)
		resGoods = append(resGoods, &m.Goods{
			Tid: int64(150209),
			Num: 1,
		})
		SendMailToUid(p.User.Uid.Hex(), mailTitle, mailContent, resGoods)
	case "sendmailrank1":
		rankId, err := strconv.ParseInt(args, 10, 64)
		if err == nil {
			rewardList, _ := lib.GetActRankRewardList(1)
			if rewardList != nil && len(rewardList) > 0 {
				reward, find := rewardList[rankId]
				if find {
					var mailTitle string = "Activity ranking Award"
					var mailContent string = fmt.Sprintf("Your rank is: %d", rankId)
					resGoods := make([]*m.Goods, 0)
					if reward.Rewards != nil && len(reward.Rewards) > 0 {
						for _, item := range reward.Rewards {
							resGoods = append(resGoods, &m.Goods{
								Tid: int64(item.Key),
								Num: int64(item.Value),
							})
						}
						SendMailToUid(p.User.Uid.Hex(), mailTitle, mailContent, resGoods)
					}
				}
			}
		}
	case "sendResMail":
		var mailTitle string = "A Gift For You"
		var mailContent string = "Wish you have a good fun"
		multiGoods := strings.Split(args, ",")
		resGoods := make([]*m.Goods, 0)
		if len(multiGoods) > 0 {
			for _, goodTidString := range multiGoods {
				goodTid, err := strconv.ParseInt(goodTidString, 10, 64)
				if err == nil {
					_, ok := data.Get("Goods", uint64(goodTid))
					if ok {
						resGoods = append(resGoods, &m.Goods{
							Tid: goodTid,
							Num: 1,
						})
					}
				}
			}
			if len(resGoods) > 0 {
				SendMailToUid(p.User.Uid.Hex(), mailTitle, mailContent, resGoods)
			}
		}
	case "actPerHour":
		activity.ActivityModule.ReCheckActActivityList(PlayersModule.GetOnlinePlayersUIDArr(), BroadCastList)
	case "actZeroTime":
		activity_rank.ActivityRankModule.ZeroTimeFunction(SendMailToUid)
	case "recheckact":
		activity.ActivityModule.ReCheckActActivityList(PlayersModule.GetOnlinePlayersUIDArr(), BroadCastList)
	case "recheckactR":
		// lastActRankId, _ := strconv.ParseInt(args, 10, 64)
		// activity_rank.ActivityRankModule.ReGroupActRank_ForGmTest(lastActRankId)
	case "recheckactR1":
		activity_rank.ActivityRankModule.ReGroupActRank()
	case "MCRemoveActActivity":
		mulcombat.Module.RemoveActActivity() // 清除旧世界Boss活动
	case "MCRecheck": // 世界Boss活动，加载活动
		mulcombat.Module.RemoveActActivity() // 删除旧的数据
		mulcombat.Module.CheckActiv()
	case "MCDivGroup": //世界Boss活动，重新分组
		mulcombat.Module.RemoveActActivity() // 删除旧的数据
		mulcombat.Module.DivMCGroup()
	case "MCRemoveGroup": //世界Boss活动，清除分组数据
		mulcombat.Module.RemoveActActivity() // 删除旧的数据
	case "MCSendReward": //世界Boss活动，发放排行奖励
		mulcombat.Module.DispatchRankReward(SendMailToUid)
	// case "heroallinit": //英雄信息重新加载
	// 	heroall.TempPageModule.Init()
	case "CountStar": //统计所有星星
		p.gmCountStar()
	case "CreateMonster": //CreateMonster:指定格子id:指定怪物tid
		lines := strings.Split(args, ":")
		if len(lines) != 2 {
			return
		}
		posId, _ := strconv.ParseInt(lines[0], 10, 64)
		monId, _ := strconv.ParseInt(lines[1], 10, 64)
		p.gmCreateMonster(posId, monId)
	case "CreateBomb": //CreateBomb:指定格子id
		lines := strings.Split(args, ":")
		if len(lines) != 1 {
			return
		}
		posId, _ := strconv.ParseInt(lines[0], 10, 64)
		p.gmCreateBomb(posId)
	case "CloseGrids": //CloseGrids 关闭没有物品的格子
		p.gmCloseGrids()
	case "MakeFriend": // 强行交朋友
		_ = lib.MakeFriendsWithPlayer(p.User, args)
	case "DeleteFriend": // 删除朋友关系
		_ = lib.DeleteFriends(p.User, args)
	case "ResetFriendData": // 重置好友数据，不删好友
		lib.ForceResetFriendsData(p.User)
	case "Achiev":
		p.gmAchiev(args)
	case "ResetAchievement": // 重置成就
		lib.CreateAchievement(p.User)
	case "AddAchiev": // 添加成就
		p.gmAddAchiev(args)
	case "ResetDailyGift": //重置每日礼包
		lib.ResetDailyGift(p.User)
	case "ResetActPack": // 重置活动礼包，宠物礼包
		lib.ResetActPack(p.User)
	case "AddCombatCard": // 添加卡牌到额外列表
		cardTid, err := strconv.ParseInt(args, 10, 64)
		if err == nil {
			lib.AddCardIndDeck(p.User, cardTid)
		}
	case "EADelActiv": // 删除委托活动
		entrust_rank.Module.DelActiv()
		entrust_activ.Module.DelActiv()
	case "EACheckActiv": // 检测委托活动
		entrust_rank.Module.CheckActiv()
		entrust_activ.Module.CheckActiv()
	case "EAChangeTask": // 切换委托任务
		entrust_activ.Module.ChangeTask()
	case "FChargeRest": // 首充状态重置
		p.User.SetFirstRechargeStatus(0)
	case "ResetRecruitTrain": // 重置新兵特训数据
		lib.ResetRecruitTrain(p.User)
	case "ResetBossPack": // 重置Boss礼包
		lib.ResetBossPack(p.User)
	case "JackpotCheckActiv": // 加载jackpot活动
		jackpot.Module.CheckActiv()
	case "JackpotAddBonus": //JackpotAddBonus:彩金类型:添加金额
		lines := strings.Split(args, ":")
		if len(lines) != 2 {
			return
		}
		typ, _ := strconv.ParseInt(lines[0], 10, 64)
		amount, _ := strconv.ParseInt(lines[1], 10, 64)
		lib.GMJackpotAddBonus(p.User, typ, amount)
	case "JackpotWin": //指定赢取大奖
		typ, _ := strconv.ParseInt(args, 10, 64)
		p.PutData("gmJackpotTyp", typ)
	case "JackpotReset":
		lib.JackpotReset(p.User)
	case "BossSlotCard": //指定boss老虎机卡片 BossSlotCard:4001
		cardTid, _ := strconv.ParseInt(args, 10, 64)
		p.PutData("BossSlotCard", cardTid)
	case "BossSlotKey": //指定boss老虎机事件 BossSlotKey:111
		key, _ := strconv.ParseInt(args, 10, 64)
		p.PutData("BossSlotKey", key)
	case "BossSlotClean": // 世界boss，清除用户自己战斗信息
		lib.BossSlotClean(p.User)
	case "UnionSignInDay": // UnionSignInDay:1 设置公会签到时间，设置加入公会天数，同时初始化积分领取次数
		day, _ := strconv.ParseInt(args, 10, 64)
		if day <= 0 {
			return
		}
		lib.SetUnionSignInDay(p.User, day)
	case "ResetSignIn": // 重置7签到时间
		p.User.ChangeLastSignInTime(0)
	case "SendRedPacket": // 发送红包
		packId, _ := strconv.ParseInt(args, 10, 64)
		if packId <= 0 {
			return
		}
		p.UnionSendRedPacketReq(packId)
	case "GiveOldActRankReward": // 拷贝老虎机排名
		activity_rank.ActivityRankModule.GiveOldActRankReward()
		// p.OldUserActRank() // 修改时间
	case "ResetPet": // 重置宠物时间和经验
		lib.ResetPet(p.User)
	case "ResetCollectProp": // 重置收集活动道具
		lib.ResetCollectProp(p.User)
	case "AddCollectProp": // 给收集活动加道具
		lines := strings.Split(args, ":")
		if len(lines) != 2 {
			return
		}
		goodTid, _ := strconv.ParseInt(lines[0], 10, 64)
		goodNum, _ := strconv.ParseInt(lines[1], 10, 64)
		lib.AddCollectProp(p.User, goodTid, goodNum, p.Send)
	case "GiveHeroGood": // 给好友卡片 GiveHeroGood:uid:tid
		lines := strings.Split(args, ":")
		if len(lines) != 2 {
			return
		}
		uid := lines[0]
		tid, _ := strconv.ParseInt(lines[1], 10, 64)
		req := &sp.GiveHeroGoodRequest{
			Tid: tid,
			Uid: uid,
		}
		p.GiveHeroGoodRequest(req)
	case "ResetHeroCount": // 重置赠送次数
		lib.ResetHeroCount(p.User)
	default:
		fmt.Println("无效的cmd:", req.Cmd)
	}
	res = &sp.GmResponse{}
	return
}

func (p *Player) gmOpenAllLayerGrids() {
	layer := p.User.GetLayer()

	for id, _ := range layer.GridList {
		res, err := p.OpenGridRequest(&sp.OpenGridRequest{GridId: id})
		if err != nil {
			continue
		}
		p.Send(res)
	}
}

func (p *Player) gmOpenAllLockBlockGrids() {
	p.gmOpenAllLayerGrids()
	for {
		_, err := lib.NextLayer(p.User)
		if err != nil {
			return
		}
		p.gmOpenAllLayerGrids()
	}
}

func (p *Player) gmLockBlockOpen(lock int64) {
	for p.User.Pos.LockBlockTid <= lock {
		p.gmOpenAllLockBlockGrids()
		_, err := lib.NextLockBlock(p.User)
		if err != nil {
			return
		}
	}
}

func (p *Player) gmChangeErengyTime(req *sp.GmRequest, tNum int64) {
	p.User.EnergyTime = tNum
	uProp := m.NewUpdateProp()
	uProp.Kvs = append(uProp.Kvs, &m.BaseKV{Key: data.GlobalEnum.EnergyTime, Val: p.User.EnergyTime})
	uProp.Kvs = append(uProp.Kvs, &m.BaseKV{Key: data.GlobalEnum.NowTime, Val: utils.TNow().Unix()})
	p.TimelyUpdateProp(req.GetType(), uProp)
	utils.AsyncFunc(func() {
		p.UpdateProp(req.GetType(), uProp)
	})
	return
}

func (p *Player) gmSlotUser(uid string) {
	//tPlayer, ok := PlayersModule.GetPlayerByName(userName)//根据名字获取玩家
	tPlayer, ok := PlayersModule.GetPlayer(uid) //根据UID获取玩家
	if !ok {
		return
	}
	// if slot.StealIsUse(tPlayer.User.Uid.Hex()) {
	// 	return
	// }
	if ruid, ok := slot_steal.StealIsUse(uid); ok {
		log.WithFields(log.Fields{
			"uid":    uid,
			"ruid":   ruid,
			"method": "gmSlotUser",
		}).Debug("指定玩家被使用")
		return
	}

	p.RemoveSlotUser()
	p.PutData("slotUser", uid)
	tPlayer.User.SetSlotNoticeUser(p.User.Uid.Hex())

	p.UpdateProp(0, &sp.UpdatePropRequest{SlotUser: lib.FormatSlotUser(nil, tPlayer.User, false)})
}

func (p *Player) gmFireUser(uid string) {
	//tPlayer, ok := PlayersModule.GetPlayerByName(userName)//根据名字获取玩家
	tPlayer, ok := PlayersModule.GetPlayer(uid) //根据UID获取玩家
	if !ok {
		return
	}
	if !tPlayer.User.IsOffLine() {
		return
	}

	// if tPlayer.User.BanTime > utils.TNow().Unix() {
	// 	return
	// }

	if tPlayer.User.Pos.LayerOpenGridNum < 2 {
		return
	}
	p.PutData("gmFireUser", tPlayer.User.Uid.Hex())
}

func (p *Player) gmFireUserOn(uid string) {
	tPlayer, ok := PlayersModule.GetPlayer(uid) //根据UID获取玩家
	if !ok {
		fmt.Println("获取玩家信息失败 uid:", uid)
		return
	}
	// if !tPlayer.User.IsOnLine() {
	// 	return
	// }

	// if tPlayer.User.BanTime > utils.TNow().Unix() {
	// 	return
	// }

	if tPlayer.User.Pos.LayerOpenGridNum < 2 {
		return
	}
	p.PutData("gmFireUserOn", tPlayer.User.Uid.Hex())
	fmt.Println("设置被烧玩家成功 uid:", uid)
}

//统计所有星星
func (p *Player) gmCountStar() {
	u := p.User

	lib.SumMapStar(u)
	lib.SumHeroStar(u)
	lib.SumPetStar(u)

	uProp := m.NewUpdateProp()
	uProp.Kvs = append(uProp.Kvs, &m.BaseKV{Key: data.GlobalEnum.Star, Val: 0})
	// p.TimelyUpdateProp(req.GetType(), uProp)
	p.UpdateProp(0, uProp)
}

func (p *Player) gmCreateMonster(posId, monId int64) {
	layer := p.User.GetLayer()

	ginfo := layer.GridList[posId]
	ginfo.Tid = 1001
	ginfo.Status = 0
	ginfo.Goods = &m.Goods{
		Tid: monId,
		Num: 1,
	}

	layer.Update(layer)
	// res, err := p.OpenGridRequest(&sp.OpenGridRequest{GridId: posId})
	// if err != nil {
	// 	return
	// }
	// p.Send(res)
}

func (p *Player) gmCreateBomb(posId int64) {
	layer := p.User.GetLayer()

	ginfo := layer.GridList[posId]
	if ginfo.Goods != nil {
		fmt.Println("该格子不为空，不能设置炸弹。")
		return
	}

	ginfo.Tid = 1002
	ginfo.Status = 0
	ginfo.Goods = &m.Goods{
		Tid: 150501,
		Num: 1,
	}

	layer.Update(layer)
	// res, err := p.OpenGridRequest(&sp.OpenGridRequest{GridId: posId})
	// if err != nil {
	// 	return
	// }
	// p.Send(res)
}

func (p *Player) gmCloseGrids() {
	layer := p.User.GetLayer()

	for _, item := range layer.GridList {
		if item.Goods != nil &&
			(item.Goods.Tid == 150402 ||
				item.Goods.Tid == 150403 ||
				item.Goods.Tid == 150404 ||
				item.Goods.Tid == 150405) {
			continue
		}
		item.Status = 1
	}
	layer.Update(layer)
}

// Achiev:成就类型:成就进度
func (p *Player) gmAchiev(args string) {
	lines := strings.Split(args, ":")
	if len(lines) != 2 {
		fmt.Println("Achiev命令错误")
		return
	}
	achType, _ := strconv.ParseInt(lines[0], 10, 64)
	val, _ := strconv.ParseInt(lines[1], 10, 64)
	lib.ModifyAchievement(p.User, achType, val)
}

// Achiev:成就类型:成就进度
func (p *Player) gmAddAchiev(args string) {
	lines := strings.Split(args, ":")
	if len(lines) != 2 {
		fmt.Println("Achiev命令错误")
		return
	}
	achType, _ := strconv.ParseInt(lines[0], 10, 64)
	val, _ := strconv.ParseInt(lines[1], 10, 64)
	lib.AddAchievProgress(p.User, achType, val)
}

// 修改记录时间为前一天，不然领不了奖励
func (p *Player) OldUserActRank() {
	oldUserActRank, err := m.GetOldUserActRank(p.User.Uid.Hex())
	if err != nil {
		return
	}
	oldUserActRank.RecordTime = utils.TNow().Add(-24 * time.Hour).Unix()
	oldUserActRank.Save()
}
